package com.christina.engine.processing.impl;

import com.alibaba.fastjson.JSONObject;
import com.christina.engine.decision.DecisionEngine;
import com.christina.engine.decision.model.DecisionRequest;
import com.christina.engine.decision.model.DecisionResult;
import com.christina.engine.intent.model.Intent;
import com.christina.engine.processing.AbstractRequestProcessor;
import com.christina.engine.processing.model.ProcessingContext;
import com.christina.engine.processing.model.ProcessingResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 决策处理器
 * 负责基于识别的意图和上下文信息制定处理决策
 */
@Component
public class DecisionProcessor extends AbstractRequestProcessor {

    private static final String PROCESSOR_NAME = "DecisionProcessor";
    private static final int PROCESSOR_ORDER = 400; // 在意图识别处理器之后执行

    private final DecisionEngine decisionEngine;

    @Autowired
    public DecisionProcessor(DecisionEngine decisionEngine) {
        super(PROCESSOR_NAME, PROCESSOR_ORDER);
        this.decisionEngine = decisionEngine;
    }

    @Override
    protected ProcessingResult doProcess(ProcessingContext context) {
        logger.debug("Starting decision making for requestId: {}", context.getRequestId());

        try {
            // 构建决策请求
            DecisionRequest decisionRequest = buildDecisionRequest(context);

            // 执行决策
            DecisionResult decisionResult = makeDecision(decisionRequest);

            // 验证决策结果
            validateDecisionResult(decisionResult);

            // 评估决策质量
            double decisionQuality = evaluateDecisionQuality(decisionRequest, decisionResult);

            // 将决策结果存储到处理上下文
            context.setDecisionResult(decisionResult);
            context.setProcessingData("decisionRequest", decisionRequest);
            context.setProcessingData("decisionQuality", decisionQuality);

            // 如果决策质量较低，记录警告
            if (decisionQuality < 0.6) {
                logger.warn("Low quality decision for requestId: {}, quality: {}, decision: {}",
                        context.getRequestId(), decisionQuality, decisionResult.getAction());
            }

            logger.debug("Decision making completed for requestId: {}, action: {}, service: {}, confidence: {}",
                    context.getRequestId(), decisionResult.getAction(),
                    decisionResult.getTargetService(), decisionResult.getConfidence());

            return ProcessingResult.builder()
                    .success(true)
                    .shouldContinue(true)
                    .processorName(PROCESSOR_NAME)
                    .resultData("decisionResult", decisionResult)
                    .resultData("decisionAction", decisionResult.getAction().name())
                    .resultData("targetService", decisionResult.getTargetService())
                    .resultData("confidence", decisionResult.getConfidence())
                    .resultData("decisionQuality", decisionQuality)
                    .build();

        } catch (Exception e) {
            logger.error("Error during decision making for requestId: {}", context.getRequestId(), e);
            throw e;
        }
    }

    /**
     * 构建决策请求
     */
    private DecisionRequest buildDecisionRequest(ProcessingContext context) {
        Intent recognizedIntent = context.getRecognizedIntent();
        if (recognizedIntent == null) {
            throw new IllegalStateException("No recognized intent found in processing context");
        }

        DecisionRequest.DecisionRequestBuilder builder = DecisionRequest.builder()
                .requestId(context.getRequestId())
                .userId(context.getUserId())
                .sessionId(context.getSessionId())
                .intent(recognizedIntent)
                .parameters(recognizedIntent.getParameters() != null ?
                        recognizedIntent.getParameters() : new JSONObject());

        // 添加用户上下文信息
        if (context.getUserContext() != null) {
            builder.userContext(extractUserContextInfo(context));
        }

        // 添加对话上下文信息
        if (context.getConversationContext() != null) {
            builder.conversationContext(extractConversationContextInfo(context));
        }

        // 添加环境信息
        //builder.environmentInfo(extractEnvironmentInfo(context));

        return builder.build();
    }

    /**
     * 执行决策
     */
    private DecisionResult makeDecision(DecisionRequest decisionRequest) {
        try {
            DecisionResult result = decisionEngine.makeDecision(decisionRequest);

            // 如果决策失败或置信度太低，尝试备选策略
            if (result.getConfidence() < 0.3 ||
                result.getAction() == DecisionResult.DecisionAction.REQUEST_MORE_INFO) {

                logger.debug("Primary decision has low confidence or requests more info, trying fallback");
                DecisionResult fallbackResult = tryFallbackDecision(decisionRequest);

                if (fallbackResult.getConfidence() > result.getConfidence()) {
                    logger.debug("Using fallback decision with higher confidence");
                    return fallbackResult;
                }
            }

            return result;

        } catch (Exception e) {
            logger.error("Decision engine failed, using emergency fallback", e);
            return createEmergencyFallbackDecision(decisionRequest);
        }
    }

    /**
     * 验证决策结果
     */
    private void validateDecisionResult(DecisionResult result) {
        if (result == null) {
            throw new IllegalStateException("Decision result cannot be null");
        }

        if (result.getAction() == null) {
            throw new IllegalStateException("Decision action cannot be null");
        }

        if (result.getTargetService() == null || result.getTargetService().trim().isEmpty()) {
            throw new IllegalStateException("Target service cannot be null or empty");
        }

        if (result.getConfidence() < 0.0 || result.getConfidence() > 1.0) {
            throw new IllegalStateException("Decision confidence must be between 0.0 and 1.0");
        }

        // 验证决策动作与目标服务的一致性
        validateActionServiceConsistency(result);
    }

    /**
     * 验证决策动作与目标服务的一致性
     */
    private void validateActionServiceConsistency(DecisionResult result) {
        DecisionResult.DecisionAction action = result.getAction();
        String targetService = result.getTargetService();

        switch (action) {
            case EXECUTE_SERVICE:
                if (!isValidServiceName(targetService)) {
                    logger.warn("Invalid service name for EXECUTE_SERVICE action: {}", targetService);
                }
                break;
            case DELEGATE_TO_HUMAN:
                if (!"human".equals(targetService)) {
                    logger.warn("Target service should be 'human' for DELEGATE_TO_HUMAN action, got: {}", targetService);
                }
                break;
            case PROVIDE_SUGGESTIONS:
                if (!targetService.equals("help") && !targetService.equals("suggestions")) {
                    logger.debug("Unusual target service for PROVIDE_SUGGESTIONS: {}", targetService);
                }
                break;
        }
    }

    /**
     * 检查是否为有效的服务名称
     */
    private boolean isValidServiceName(String serviceName) {
        return serviceName != null &&
               (serviceName.equals("travel") ||
                serviceName.equals("chat") ||
                serviceName.equals("user") ||
                serviceName.equals("notification") ||
                serviceName.equals("task"));
    }

    /**
     * 评估决策质量
     */
    private double evaluateDecisionQuality(DecisionRequest request, DecisionResult result) {
        try {
            return decisionEngine.evaluateDecisionQuality(request, result);
        } catch (Exception e) {
            logger.error("Failed to evaluate decision quality", e);
            return 0.5; // 默认中等质量
        }
    }

    /**
     * 尝试备选决策策略
     */
    private DecisionResult tryFallbackDecision(DecisionRequest request) {
        Intent.IntentType intentType = request.getIntent().getType();

        // 基于意图类型的简单决策规则
        DecisionResult.DecisionAction action;
        String targetService;
        double confidence;
        String reasoning;

        switch (intentType) {
            case TRAVEL_PLANNING:
            case TRAVEL_BOOKING:
            case TRAVEL_INQUIRY:
                action = DecisionResult.DecisionAction.EXECUTE_SERVICE;
                targetService = "travel";
                confidence = 0.7;
                reasoning = "基于意图类型的备选决策：出行服务";
                break;

            case GENERAL_CHAT:
            case QUESTION_ANSWER:
                action = DecisionResult.DecisionAction.EXECUTE_SERVICE;
                targetService = "chat";
                confidence = 0.6;
                reasoning = "基于意图类型的备选决策：聊天服务";
                break;

            case USER_REGISTRATION:
            case USER_LOGIN:
            case USER_PROFILE:
                action = DecisionResult.DecisionAction.EXECUTE_SERVICE;
                targetService = "user";
                confidence = 0.8;
                reasoning = "基于意图类型的备选决策：用户服务";
                break;

            case HELP_REQUEST:
                action = DecisionResult.DecisionAction.PROVIDE_SUGGESTIONS;
                targetService = "help";
                confidence = 0.5;
                reasoning = "基于意图类型的备选决策：提供帮助";
                break;

            case COMPLAINT:
                action = DecisionResult.DecisionAction.DELEGATE_TO_HUMAN;
                targetService = "human";
                confidence = 0.6;
                reasoning = "基于意图类型的备选决策：转人工处理";
                break;

            default:
                action = DecisionResult.DecisionAction.REQUEST_MORE_INFO;
                targetService = "clarification";
                confidence = 0.4;
                reasoning = "基于意图类型的备选决策：请求更多信息";
        }

        return DecisionResult.builder()
                .decisionId("fallback_" + System.currentTimeMillis())
                .action(action)
                .targetService(targetService)
                .confidence(confidence)
                .reasoning(reasoning)
                .decisionTime(LocalDateTime.now())
                .status(DecisionResult.DecisionStatus.COMPLETED)
                .executionParameters(request.getParameters())
                .build();
    }

    /**
     * 创建紧急备选决策
     */
    private DecisionResult createEmergencyFallbackDecision(DecisionRequest request) {
        return DecisionResult.builder()
                .decisionId("emergency_" + System.currentTimeMillis())
                .action(DecisionResult.DecisionAction.PROVIDE_SUGGESTIONS)
                .targetService("fallback")
                .confidence(0.1)
                .reasoning("决策引擎异常，使用紧急备选策略")
                .decisionTime(LocalDateTime.now())
                .status(DecisionResult.DecisionStatus.COMPLETED)
                .executionParameters(new JSONObject())
                .build();
    }

    /**
     * 提取用户上下文信息
     */
    private Map<String, Object> extractUserContextInfo(ProcessingContext context) {
        Map<String, Object> userInfo = new HashMap<>();

        var userContext = context.getUserContext();
        userInfo.put("userId", userContext.getUserId());

        if (userContext.getProfile() != null) {
            userInfo.put("language", userContext.getProfile().getLanguage());
            userInfo.put("hasProfile", true);
        } else {
            userInfo.put("hasProfile", false);
        }

        if (userContext.getPreferences() != null) {
            userInfo.put("preferences", userContext.getPreferences().getCustomPreferences());
            userInfo.put("hasPreferences", true);
        } else {
            userInfo.put("hasPreferences", false);
        }

        if (userContext.getBehaviorHistory() != null) {
            userInfo.put("behaviorHistorySize", userContext.getBehaviorHistory().size());
        }

        return userInfo;
    }

    /**
     * 提取对话上下文信息
     */
    private Map<String, Object> extractConversationContextInfo(ProcessingContext context) {
        Map<String, Object> conversationInfo = new HashMap<>();

        var conversationContext = context.getConversationContext();
        conversationInfo.put("sessionId", conversationContext.getSessionId());
        conversationInfo.put("currentTopic", conversationContext.getCurrentTopic());
        conversationInfo.put("state", conversationContext.getState().name());

        if (conversationContext.getConversationHistory() != null) {
            conversationInfo.put("historySize", conversationContext.getConversationHistory().size());

            // 获取最近的对话轮次
            if (!conversationContext.getConversationHistory().isEmpty()) {
                var lastTurn = conversationContext.getConversationHistory().get(
                        conversationContext.getConversationHistory().size() - 1);
                conversationInfo.put("lastUserInput", lastTurn.getUserInput());
                conversationInfo.put("lastAssistantResponse", lastTurn.getAssistantResponse());
            }
        }

        return conversationInfo;
    }

    /**
     * 提取环境信息
     */
    private Map<String, Object> extractEnvironmentInfo(ProcessingContext context) {
        Map<String, Object> envInfo = new HashMap<>();

        envInfo.put("requestId", context.getRequestId());
        envInfo.put("requestTime", context.getOriginalRequest().getRequestTime());
        envInfo.put("requestType", context.getOriginalRequest().getRequestType().name());

        if (context.getOriginalRequest().getClientInfo() != null) {
            var clientInfo = context.getOriginalRequest().getClientInfo();
            envInfo.put("deviceType", clientInfo.getDeviceType());
            envInfo.put("platform", clientInfo.getPlatform());
            envInfo.put("language", clientInfo.getLanguage());
        }

        return envInfo;
    }

    @Override
    protected void preProcess(ProcessingContext context) {
        super.preProcess(context);
        context.updateState("MAKING_DECISION");
    }

    @Override
    protected void postProcess(ProcessingContext context, ProcessingResult result) {
        super.postProcess(context, result);
        if (result.isSuccess()) {
            context.updateState("DECISION_MADE");
        } else {
            context.updateState("DECISION_FAILED");
        }
    }

    @Override
    public boolean supports(ProcessingContext context) {
        // 决策处理器需要已识别的意图
        return context != null &&
               context.getOriginalRequest() != null &&
               context.getUserId() != null &&
               context.getSessionId() != null &&
               context.getRecognizedIntent() != null;
    }

    @Override
    protected ProcessingResult handleError(ProcessingContext context, Exception exception) {
        logger.warn("Decision making failed, using emergency fallback for requestId: {}",
                context.getRequestId(), exception);

        try {
            // 创建紧急决策请求
            DecisionRequest emergencyRequest = DecisionRequest.builder()
                    .requestId(context.getRequestId())
                    .userId(context.getUserId())
                    .sessionId(context.getSessionId())
                    .intent(context.getRecognizedIntent() != null ?
                            context.getRecognizedIntent() : createUnknownIntent())
                    .parameters(new JSONObject())
                    .build();

            DecisionResult emergencyDecision = createEmergencyFallbackDecision(emergencyRequest);
            context.setDecisionResult(emergencyDecision);
            context.setProcessingData("decisionError", exception.getMessage());

            return ProcessingResult.builder()
                    .success(true) // 虽然决策失败，但使用紧急备选继续处理
                    .shouldContinue(true)
                    .processorName(PROCESSOR_NAME)
                    .resultData("decisionResult", emergencyDecision)
                    .resultData("decisionAction", emergencyDecision.getAction().name())
                    .resultData("targetService", emergencyDecision.getTargetService())
                    .resultData("confidence", emergencyDecision.getConfidence())
                    .resultData("emergencyFallbackUsed", true)
                    .resultData("error", exception.getMessage())
                    .build();

        } catch (Exception e) {
            logger.error("Failed to create emergency fallback decision for requestId: {}",
                    context.getRequestId(), e);
            return super.handleError(context, e);
        }
    }

    /**
     * 创建未知意图
     */
    private Intent createUnknownIntent() {
        return Intent.builder()
                .type(Intent.IntentType.UNKNOWN)
                .name("未知意图")
                .description("决策处理器错误处理中创建的未知意图")
                .confidence(0.1)
                .parameters(new JSONObject())
                .build();
    }
}